﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using System.Threading;
using Microsoft.Xna.Framework.GamerServices;

namespace PuzzleCoop
{
    public static class GameScreenManager
    {
        public static Game game;
        static Stack<GameScreen> GameScreens = new Stack<GameScreen>();

        static Texture2D blackScreen;
        static GameScreen transScreen = null;
        static bool isTransitioningIn = false;
        static bool isTransitioningOut = false;
        static int transDuration = 250;
        static double transTimer = 0;
        static GameScreen startScreen = null;

        /// <summary>
        /// Função que inicializa o GameScreenManager. Deve ser chamada no LoadContent da Game.
        /// </summary>
        /// <param name="game">Game que a manager tratará.</param>
        /// <param name="startScreen">Primeira tela do jogo.</param>
        public static void Start(Game game, GameScreen startScreen)
        {
            GameScreenManager.game = game;
            Input.Start();
            blackScreen = game.Content.Load<Texture2D>("Images\\BlackScreen");
            GameScreenManager.startScreen = startScreen;
            Push(startScreen);
        }

        public static void Update(GameTime gameTime)
        {
            if (isTransitioningIn) return;
            Input.Update(gameTime);
            if (GameScreens.Count > 0) GameScreens.Peek().Update(gameTime);
        }

        public static void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            spriteBatch.GraphicsDevice.Clear(Color.DarkGray);
            if (isTransitioningIn) DrawTransitionIn(gameTime, spriteBatch);
            else
            {
                if (GameScreens.Count > 0) GameScreens.Peek().Draw(gameTime, spriteBatch);
                if (isTransitioningOut) DrawTransitionOut(gameTime, spriteBatch);
            }
        }

        public static void DrawTransitionIn(GameTime gameTime, SpriteBatch spriteBatch)
        {
            transTimer += gameTime.ElapsedGameTime.TotalMilliseconds;
            if (transTimer > transDuration)
            {
                transTimer = transDuration;
                isTransitioningIn = false;
                isTransitioningOut = true;
            }
            float a = (float)(transTimer / (transDuration / 2));
            if (a > 1) a = 1;
            if (transScreen != null) transScreen.Draw(gameTime, spriteBatch);
            spriteBatch.Draw(blackScreen, Vector2.Zero, new Color(0f, 0f, 0f, a));
        }

        public static void DrawTransitionOut(GameTime gameTime, SpriteBatch spriteBatch)
        {
            transTimer -= gameTime.ElapsedGameTime.TotalMilliseconds;
            if (transTimer < 0)
            {
                transTimer = 0;
                isTransitioningIn = false;
                isTransitioningOut = false;
                return;
            }
            float a = (float)(transTimer / (transDuration / 2));
            if (a > 1) a = 1; if (a < 0) a = 0;
            spriteBatch.Draw(blackScreen, Vector2.Zero, new Color(0f, 0f, 0f, a));
        }

        public static void Push(GameScreen gameScreen)
        {
            isTransitioningIn = true;
            if (!(gameScreen is LoadScreen) && GameScreens.Count > 0) transScreen = GameScreens.Peek();
            GameScreens.Push(gameScreen);
            if (!(gameScreen is LoadScreen)) Push(new LoadScreen(gameScreen));
        }

        public static void Pop()
        {
            isTransitioningIn = true;
            transScreen = GameScreens.Pop();
        }

        public static void Reset()
        {
            GameScreens.Clear();
            GameScreenManager.Push(startScreen);
        }

        public static T Load<T>(String asset)
        {
            return game.Content.Load<T>(asset);
        }
    }
}
